package gui;

import java.lang.reflect.Method;
import java.util.LinkedList;

public class ClasseEMetodos 
{
	private Class classe;
	private LinkedList<Method> metodos;
	private LinkedList<DeclaracaoDeMetodo> declaracaoDosMetodos; //na mesma ordem dos metodos acima
	
	/*iremos precisar do endereco do arquivo java da classe para criar as declaracoes dos metodos dela*/
	public ClasseEMetodos(Class c, String enderecoParaArquivoJavaDaClasse)
	{
		this.classe = c;
		Method[] metodosEmArray = this.classe.getDeclaredMethods();
		this.metodos = new LinkedList<Method>();
		
		for(int h = 0; h < metodosEmArray.length; h++)
		{
			Method umMetodo = metodosEmArray[h];
			this.metodos.add(umMetodo);
		}
		
		this.declaracaoDosMetodos = new LinkedList<DeclaracaoDeMetodo>();
		
		for(int i = 0; i < metodos.size(); i++)
		{
			Method umMetodo = metodos.get(i);
			DeclaracaoDeMetodo umaDeclaracao =
					new DeclaracaoDeMetodo(umMetodo, enderecoParaArquivoJavaDaClasse);
			if(umaDeclaracao.getNomesDosParametrosDeEntrada() == null)
			{
				/*se os nomes dos parametros for null, significa que nao conseguimos pegar
				 * os nomes dos parametros do metodo, mas ele TEM parametros. Eh melhor
				 * descartar esse metodo, melhor nao usa-lo nunca mais. Vamos retirar esse metodo dos metodos da classe*/
				this.metodos.remove(umMetodo);
			}
			else
			{
				this.declaracaoDosMetodos.add(umaDeclaracao);
			}
		}
	}

	public Class getClasse() {
		return classe;
	}

	public void setClasse(Class classe) {
		this.classe = classe;
	}

	public LinkedList<Method> getMetodos() {
		return metodos;
	}

	public void setMetodos(LinkedList<Method> metodos) {
		this.metodos = metodos;
	}
	
	public LinkedList<DeclaracaoDeMetodo> getDeclaracaoDosMetodos() 
	{
		return declaracaoDosMetodos;
	}
	
	/*dado um metodo dessa classe, pegaremos sua declaracao ou retornaremos null
	 * se o metodo nao pertence a classe*/
	public DeclaracaoDeMetodo pegarDeclaracaoDeMetodo(Method metodo)
	{
		for(int i = 0; i < this.declaracaoDosMetodos.size(); i++)
		{
			DeclaracaoDeMetodo umaDeclaracao = this.declaracaoDosMetodos.get(i);
			if(umaDeclaracao.getMetodoAssociado() == metodo)
			{
				return umaDeclaracao;
			}
		}
		
		return null; //se nao achamos a declaracao do metodo nessa classe
	}
}
